package service

import (
	"context"
	"fmt"
	"os"
	"pmservice/dbfactory"
	"strings"
	"syscall"

	"github.com/99designs/gqlgen/graphql"
)

type Service struct {
	Orm *dbfactory.ORM
}

func NewService(orm *dbfactory.ORM) *Service {
	return &Service{Orm: orm}
}

// GetPreloads Fieldset
func GetPreloads(ctx context.Context) []string {
	return GetNestedPreloads(
		graphql.GetOperationContext(ctx),
		graphql.CollectFieldsCtx(ctx, nil),
		"",
	)
}

// PrefixJoin graphql请求前缀存在，需要增加.分隔符，如果没有前缀，不需要分隔符
func PrefixJoin(prefix1, prefix2 string) string {
	if prefix1 != "" {
		return strings.Join([]string{prefix1, prefix2}, ".")
	}
	return prefix2
}

func GetNestedPreloads(ctx *graphql.OperationContext, fields []graphql.CollectedField, prefix string) (preloads []string) {
	for _, column := range fields {
		prefixColumn := GetPreloadString(prefix, column.Name)
		preloads = append(preloads, prefixColumn)
		preloads = append(preloads, GetNestedPreloads(ctx, graphql.CollectFields(ctx, column.Selections, nil), prefixColumn)...)
	}
	return
}

func GetPreloadString(prefix, name string) string {
	if len(prefix) > 0 {
		return prefix + "." + name
	}
	return name
}

// func GetByPagerInfo(page *model.PagerInfo, objs []interface{}) []interface{} {
// 	ret := make([]interface{}, 0)
// 	j := 0
// 	num := len(objs) - page.Offset
// 	// Page.num=0: 获取剩余全部记录
// 	// Page.num>0: 获取不超过Page.num个剩余记录
// 	if page.Number > 0 && num > page.Number {
// 		num = page.Number
// 	}
// 	for i := page.Offset; j < num; i++ {
// 		ret = append(ret, objs[i])
// 		j++
// 	}
// 	return ret
// }

func HasField(ctx context.Context, field string) bool {
	if ctx == context.Background() || ctx == context.TODO() {
		return false
	}
	// Get Query Field Collection
	fields := GetPreloads(ctx)
	for _, v := range fields {
		if v == field {
			return true
		}
	}
	return false
}

// ServiceRestart is the resolver for the ServiceRestart field.
func (s *Service) ServiceRestart(ctx context.Context) (bool, error) {
	fmt.Println("restart...")
	exe, err := os.Executable()
	if err != nil {
		return false, err
	}

	// 替换当前进程
	err = syscall.Exec(exe, os.Args, os.Environ())
	if err != nil {
		fmt.Println("restart fail:", err)
	}

	return true, nil
}

// ServiceLogGet is the resolver for the ServiceLogGet field.
func (s *Service) ServiceLogGet(ctx context.Context, lines *int) (string, error) {
	panic(fmt.Errorf("not implemented: ServiceLogGet - ServiceLogGet"))
}
